package com.wiscamp.ninechapters.problems.adapter.resources.collections;


import com.wiscamp.ninechapters.problems.application.dto.commands.collections.*;
import com.wiscamp.ninechapters.problems.application.dto.vo.collections.ProblemCollectionVO;
import com.wiscamp.ninechapters.problems.application.dto.vo.problems.ProblemVO;
import com.wiscamp.ninechapters.problems.application.services.ProblemCollectionAppService;
import cube.ddd.adapter.RestResponse;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.aspect.HandleResourceException;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.domain.BaseRepository;
import cube.ddd.utils.ResourceUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.ws.rs.core.Context;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

/**
 * 题集服务端点
 *
 * @author yifeng
 */
@RestController
@RequestMapping("/api/Problems")
@Tag(name = "题库-题集信息")
public class ProblemCollectionController extends BaseRepository {

    private final ProblemCollectionAppService problemCollectionAppService;

    public ProblemCollectionController(ProblemCollectionAppService problemCollectionAppService) {
        this.problemCollectionAppService = problemCollectionAppService;
    }

    /**
     * 通过题集编号获取题集
     *
     * @param request
     * @param response
     * @param collectionId
     * @return
     */
    @GetMapping("ProblemCollections/{collectionId}")
    @Operation(summary = "通过题集编号获取题集")
    @HandleResourceException
    public RestResponse<ProblemCollectionVO> getProblemCollection(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                  @PathVariable("collectionId") long collectionId) {
        return ResourceUtils.getById(request, response, collectionId, problemCollectionAppService::getProblemCollection);
    }

    /**
     * 通过机构编号获取题集列表
     *
     * @param organizationId
     * @return 题集列表
     */
    @GetMapping("Organizations/{organizationId}/ProblemCollections")
    @Operation(summary = "通过机构编号获取题集列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemCollectionVO>> getProblemCollectionsByOrganization(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                             @PathVariable("organizationId") long organizationId) {
        return ResourceUtils.getListById(request, response, organizationId, problemCollectionAppService::getProblemCollectionsByOrganization);
    }

    @GetMapping("Exams/{examId}/ProblemCollections")
    @Operation(summary = "通过考试编号获取题集列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemCollectionVO>> getProblemCollectionsByExam(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                             @PathVariable("examId") long examId) {
        return ResourceUtils.getListById(request, response, examId, problemCollectionAppService::getProblemCollectionsByExam);
    }

    /**
     * 根据机构编号和题集代码获取题集
     *
     * @param organizationId
     * @param collectionCode
     * @return
     */
    @GetMapping("Organizations/{organizationId}/ProblemCollections/Code/{collectionCode}")
    @Operation(summary = "根据机构编号和题集代码获取题集")
    @HandleResourceException
    public RestResponse<ProblemCollectionVO> getProblemCollectionByCode(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                        @PathVariable("organizationId") long organizationId,
                                                                        @PathVariable("collectionCode") String collectionCode) {
        return ResourceUtils.getByTextAndId(request, response, collectionCode, organizationId, problemCollectionAppService::getProblemCollectionByCode);
    }


    /**
     * 根据机构编号和题集名称获取题集列表
     *
     * @param organizationId
     * @param collectionName
     * @return
     */
    @GetMapping("Organizations/{organizationId}/ProblemCollections/Name/{collectionName}")
    @Operation(summary = "根据机构编号和题集名称获取题集列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemCollectionVO>> getProblemCollectionByName(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                    @PathVariable("organizationId") long organizationId,
                                                                                    @PathVariable("collectionName") String collectionName) {
        return ResourceUtils.getListByTextAndId(request, response, collectionName, organizationId, problemCollectionAppService::getProblemCollectionsByName);
    }

    @GetMapping("ProblemCollections/{collectionId}/Problems/{problemId}/Next")
    @Operation(summary = "根据机构编号和题编号获取题所在题集的下一道题")
    @HandleResourceException
    public RestResponse<Long> getNextProblemId(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                               @PathVariable("collectionId") long collectionId,
                                               @PathVariable("problemId") long problemId) {
        long nextProblemId = problemCollectionAppService.getNextProblemId(collectionId, problemId);
        return ResourceUtils.getOkResponse(request, response, nextProblemId);
    }

    /**
     * 根据机构编号和题集名称前缀获取题集列表
     *
     * @param request
     * @param response
     * @param organizationId
     * @param name
     * @return
     */
    @GetMapping("Organizations/{organizationId}/ProblemCollections/Name/Contains/{name}")
    @Operation(summary = "根据机构编号和题集名称前缀获取题集列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemCollectionVO>> getProblemCollectionsByNameContains(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                             @PathVariable("organizationId") long organizationId,
                                                                                             @PathVariable("name") String name) {
        return ResourceUtils.getListByTextAndId(request, response, name, organizationId,
                problemCollectionAppService::getProblemCollectionsByNameContains);
    }

    @GetMapping("Organizations/{organizationId}/ProblemCollections/Name/Contains/{name}/{gradeLevel}")
    @Operation(summary = "根据机构编号和题集代码前缀获取题集列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemCollectionVO>> getProblemCollectionsByNameContains(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                             @PathVariable("organizationId") long organizationId,
                                                                                             @PathVariable("name") String name,
                                                                                             @PathVariable("gradeLevel") String gradeLevel) {
        var collections = problemCollectionAppService.getProblemCollectionsByNameContains(name, organizationId, gradeLevel);
        return ResourceUtils.getOkResponse(request, response, collections);
    }


    /**
     * 通过题集编号删除题集
     *
     * @param id
     * @return
     */
    @PutMapping("ProblemCollections/Actions/Delete")
    @Operation(summary = "通过题集编号删除题集")
    @HandleResourceException
    public RestResponse<Boolean> deleteProblemCollection(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                         @RequestBody DeleteCommand command) {
        return ResourceUtils.delete(request, response, command, problemCollectionAppService::deleteProblemCollection);
    }

    @DeleteMapping("ProblemCollections/{id}")
    @Operation(summary = "通过题集编号删除题集")
    @HandleResourceException
    public RestResponse<Boolean> deleteProblemCollection(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                         @PathVariable("id") long id) {
        var command = new DeleteCommand();
        command.setId(id);
        return ResourceUtils.delete(request, response, command, problemCollectionAppService::deleteProblemCollection);
    }

    /**
     * 创建题集
     *
     * @param command
     * @return
     */
    @PostMapping("ProblemCollections")
    @Operation(summary = "创建题集")
    @HandleResourceException
    public RestResponse<ProblemCollectionVO> createProblemCollection(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                     @RequestBody CreateProblemCollectionCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command, problemCollectionAppService::createProblemCollection);
    }

    /**
     * 更新题集
     *
     * @param command
     * @return
     */
    @PutMapping("ProblemCollections")
    @Operation(summary = "更新题集")
    @HandleResourceException
    public RestResponse<ProblemCollectionVO> updateProblemCollection(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                     @RequestBody UpdateProblemCollectionCommand command) {
        return ResourceUtils.createOrUpdate(request, response, command,
                problemCollectionAppService::updateProblemCollection);
    }


    /**
     * 分页获取题集列表
     *
     * @return 题集列表
     */
    @PostMapping("ProblemCollections/Query")
    @Operation(summary = "分页获取题集列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemCollectionVO>> getProblemCollectionsByQuery(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                                      @RequestBody PagedQuery query) {
        return ResourceUtils.getPagedObjectsByQuery(request, response, query,
                problemCollectionAppService::getProblemCollectionsByQuery);
    }

    @DeleteMapping("ProblemCollections/Actions/Remove/Problem")
    @Operation(summary = "通过题集编号和题编号从题集中移除题")
    @HandleResourceException
    public RestResponse<Boolean> removeCollectionProblem(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                         @RequestBody RemoveCollectionProblemCommand command) {
        var success = problemCollectionAppService.removeProblem(command);
        return ResourceUtils.getOkResponse(request, response, success);
    }

    @DeleteMapping("ProblemCollections/Actions/Remove/Problem/{problemId}")
    @Operation(summary = "通过题集编号和题编号从题集中移除题")
    @HandleResourceException
    public RestResponse<Boolean> removeCollectionProblem(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                         @PathVariable("problemId") long problemId) {
        var success = problemCollectionAppService.removeProblem(problemId);
        return ResourceUtils.getOkResponse(request, response, success);
    }

    /**
     * 批量设置题集中所有题与标签关联
     *
     * @param poolId
     * @param groupName
     * @param tagName
     * @return
     */
    @PostMapping("ProblemCollections/Actions/Tag")
    @Operation(summary = "批量设置题集中所有题与标签关联")
    @HandleResourceException
    public RestResponse<Boolean> batchTag(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                          @RequestBody BatchTagCommand command) {
        var result = problemCollectionAppService.batchTagProblems(command);
        return ResourceUtils.getOkResponse(request, response, result);
    }

    /**
     * 批量取消设置题集中所有题与标签关联
     *
     * @param poolId
     * @param groupName
     * @param tagName
     * @return
     */
    @PostMapping("ProblemCollections/Actions/Untag")
    @Operation(summary = "批量设置题集中所有题与标签关联")
    @HandleResourceException
    public RestResponse<Boolean> batchUntag(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                          @RequestBody BatchUntagCommand command) {
        var result = problemCollectionAppService.batchUntagProblems(command);
        return ResourceUtils.getOkResponse(request, response, result);
    }

    @GetMapping("ProblemCollections/{collectionId}/Problems")
    @Operation(summary = "通过题集编号获取题列表")
    @HandleResourceException
    public RestResponse<Collection<ProblemVO>> getProblemsByCollection(@Context HttpServletRequest request, @Context HttpServletResponse response,
                                                                       @PathVariable("collectionId") long collectionId) {
        return ResourceUtils.getListById(request, response, collectionId, problemCollectionAppService::getProblemsByCollection);
    }
}
